package tagcapturer;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import tagcapturer.CaptureEvent.BizTransaction;

/**
 * EPCIS Capture Interface Client. 
 * 
 * @author Anthony Lam
 */
public class CaptureEventGenerator {

    public final static String EPCIS_STATUS_FAIL = "Fail";
    public final static String EPCIS_STATUS_SUCCESS = "Success";
    /**
     * The client thourgh which the EPCISEvents will be sent to the repository's
     * Capture Operations Module.
     */
    private EpcisCaptureClient client;

    /**
     * The possible values for the "actions" parameter.
     */
    private final String[] actions = {
            "ADD", "OBSERVE", "DELETE"
    };

    /**
     * The four possible event types, in human readable form.
     */
    private final String[] eventTypes = {
            "Object event", "Aggregation event", "Quantity event", "Transaction event"
    };

    /**
     * The four possible event types, used for XML creation.
     */
    private final String[] xmlEventNode = {
            "ObjectEvent", "AggregationEvent", "QuantityEvent", "TransactionEvent"
    };

    /**
     * Holds all the examples.
     */
    private ExampleEvents exampleEvents = new ExampleEvents();

    /**
     * Constructs a new CaptureClientGui initialized with a default address.
     */
    public CaptureEventGenerator() {
        //this(null);
        this.client = new EpcisCaptureClient(null);
    }

    /**
     * Constructs a new CaptureClientGui initialized with the given address.
     * 
     * @param address
     *            The address to which the CaptureClient should sent its capture
     *            events.
     */
    public CaptureEventGenerator(final String address) {
        this.client = new EpcisCaptureClient(address);
    }

//            CaptureEvent ex = (CaptureEvent) exampleEvents.examples.get(selected);
//            if (ex.getEventTime() == null) {
//                /* set eventTime to current time */
//                java.util.Date now = new java.util.Date();
//                Calendar cal = Calendar.getInstance();
//                cal.setTime(now);
//                /* set default to something simple and ISO 8601 compatible */
//                mwEventTimeTextField.setText(cal.get(Calendar.YEAR) + "-"
//                        + cal.get(Calendar.MONTH) + "-"
//                        + cal.get(Calendar.DAY_OF_MONTH) + "T"
//                        + cal.get(Calendar.HOUR_OF_DAY) + ":"
//                        + cal.get(Calendar.MINUTE) + ":"
//                        + cal.get(Calendar.SECOND));
//            } else {
//                mwEventTimeTextField.setText(ex.getEventTime());
//            }

    /**
     * The user pushed the Generate event-button. This method converts the data
     * from the user interface to XML, POSTs it to the server and displays the
     * answer to the user. It also does some simple client-side checks to see if
     * all necessary fields are filled.
     */
    public String generateEvent(CaptureEvent captureEvent) {
        String epcisStatus = EPCIS_STATUS_FAIL; 
        try {
            /* DOM-tree stuff */
            Document document = null;
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            DOMImplementation impl = builder.getDOMImplementation();

            /* temporary element variable */
            Element element = null;

            /* create empty document and fetch root */
            document = impl.createDocument("urn:epcglobal:epcis:xsd:1", "epcis:EPCISDocument", null);
            Element root = document.getDocumentElement();

            Date now = new Date();
            SimpleDateFormat dateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
            root.setAttribute("creationDate", dateTime.format(now));
            root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
            root.setAttribute("xmlns:epcis", "urn:epcglobal:epcis:xsd:1");
            root.setAttribute("schemaVersion", "1.0");
            element = document.createElement("EPCISBody");
            root.appendChild(element);
            root = element;
            element = document.createElement("EventList");
            root.appendChild(element);
            root = element;
            element = document.createElement(xmlEventNode[captureEvent.getType()]);
            root.appendChild(element);
            root = element;

            /* eventTime */
            if (!addEventTime(document, root, captureEvent.getEventTime())) {
                System.out.println("Please specify the event time (i.e. 2005-07-18T17:33:20.231)");
                return epcisStatus;
            }

            // record Time is set by the capture-Interface
            if (xmlEventNode[captureEvent.getType()].equals("ObjectEvent")) {
                if (!addEpcList(document, root, captureEvent.getEpcList())) {
                    System.out.println("Please specify at least one EPC");
                    return epcisStatus;
                }
                addAction(document, root, actions[captureEvent.getAction()]);
                addBizStep(document, root, captureEvent.getBizStep());
                addDisposition(document, root, captureEvent.getDisposition());
                addReadPoint(document, root, captureEvent.getReadPoint());
                addBizLocation(document, root, captureEvent.getBizLocation());
                addBizTransactionList(document, root, captureEvent.getBizTransaction());
            } else if (xmlEventNode[captureEvent.getType()].equals("AggregationEvent")) {
                if (!addParentId(document, root, captureEvent.getParentID())
                        && ! actions[captureEvent.getAction()].equals("OBSERVE")) {
                    System.out.println("Because action is OBSERVE, it's required to specify a ParentID");
                    return epcisStatus;
                }
                if (!addChildEpcList(document, root, captureEvent.getChildEPCs())) {
                    System.out.println("Please specify at least one EPC");
                    return epcisStatus;
                }
                addAction(document, root, actions[captureEvent.getAction()]);
                addBizStep(document, root, captureEvent.getBizStep());
                addDisposition(document, root, captureEvent.getDisposition());
                addReadPoint(document, root, captureEvent.getReadPoint());
                addBizLocation(document, root, captureEvent.getBizLocation());
                addBizTransactionList(document, root, captureEvent.getBizTransaction());
            } else if (xmlEventNode[captureEvent.getType()].equals("QuantityEvent")) {
                if (!addEpcClass(document, root, captureEvent.getEpcClass())) {
                    System.out.println("Please specify an EPC class (URI)");
                    return epcisStatus;
                }
                if (!addQuantity(document, root, captureEvent.getQuantity())) {
                    System.out.println("Please specify a quantity value (integer number)");
                    return epcisStatus;
                }
                addBizStep(document, root, captureEvent.getBizStep());
                addDisposition(document, root, captureEvent.getDisposition());
                addReadPoint(document, root, captureEvent.getReadPoint());
                addBizLocation(document, root, captureEvent.getBizLocation());
                addBizTransactionList(document, root, captureEvent.getBizTransaction());
            } else if (xmlEventNode[captureEvent.getType()].equals("TransactionEvent")) {
                if (!addBizTransactionList(document, root, captureEvent.getBizTransaction())) {
                    System.out.println("Please specify at least one business transaction (ID, Type)");
                    return "Exception";
                }
                addParentId(document, root, captureEvent.getParentID());
                if (!addEpcList(document, root, captureEvent.getEpcList())) {
                    System.out.println("Please specify at least one EPC");
                    return "Exception";
                }
                addAction(document, root, actions[captureEvent.getAction()]);
                addBizStep(document, root, captureEvent.getBizStep());
                addDisposition(document, root, captureEvent.getDisposition());
                addReadPoint(document, root, captureEvent.getReadPoint());
                addBizLocation(document, root, captureEvent.getBizLocation());
            }

            DOMSource domsrc = new DOMSource(document);

            StringWriter out = new StringWriter();
            StreamResult streamResult = new StreamResult(out);
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer serializer = tf.newTransformer();

            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
            serializer.transform(domsrc, streamResult);

            String eventXml = out.toString();
            String postData = eventXml;

            System.out.println("sending HTTP POST data:\n");
            System.out.println(postData);

            /* connect the service, write out xml and get response */
            String response = client.capture(postData);

            if (response.contains("200 OK")) {
                System.out.println(response);
                epcisStatus = EPCIS_STATUS_SUCCESS;
            } else {
                //error
                System.out.println(response);
            }
            
        } catch (MalformedURLException mfue) {
            mfue.printStackTrace();
            System.out.println(mfue.getMessage());
         } catch (IOException ioe) {
            ioe.printStackTrace();
            System.out.println(ioe.getMessage());
        } catch (TransformerException te) {
            te.printStackTrace();
            System.out.println(te.getMessage());
        } catch (ParserConfigurationException pce) {
            pce.printStackTrace();
            System.out.println(pce.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
        return epcisStatus;
    }

    /**
     * Adds the Quantity to the XML-File. Possible for the QuantityEvent
     * (required).
     * 
     * @param document
     *            The DOM-Tree where is has to inserted.
     * @param root
     *            The element, where it has to be added.
     * @return If the value had been set in the GUI.
     */
    private Boolean addQuantity(final Document document, final Element root, int quantity) {
        Element element;
        try {
            Integer n = new Integer(quantity);
            element = document.createElement("quantity");
            element.appendChild(document.createTextNode(n.toString()));
            root.appendChild(element);
            return true;
        } catch (NumberFormatException nfe) {
            return false;
        }
    }

    /**
     * Adds the ChildEPCList to the XML-File. Possible for the QuantityEvent
     * (required).
     * 
     * @param document
     *            The DOM-Tree where is has to inserted.
     * @param root
     *            The element, where it has to be added.
     * @return If the value had been set in the GUI.
     */
    private Boolean addEpcClass(final Document document, final Element root, final String epcClass) {
        if (!epcClass.equals("")) {
            Element element;
            element = document.createElement("epcClass");
            element.appendChild(document.createTextNode(epcClass));
            root.appendChild(element);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Adds the ChildEPCList to the XML-File. Possible for - AggregationEvent
     * (required) - TransactionEvent (required)
     * 
     * @param document
     *            the DOM-Tree where is has to inserted
     * @param root
     *            the element, where it has to be added
     * @return if the value had been set in the GUI
     */
    private Boolean addChildEpcList(final Document document, final Element root, final String childEpcList) {
        if (!childEpcList.equals("")) {
            Element element;
            element = document.createElement("childEPCs");
            Element epcNode = null;
            String[] epcs = childEpcList.split(" ");
            for (String epc : epcs) {
                epcNode = document.createElement("epc");
                epcNode.appendChild(document.createTextNode(epc));
                element.appendChild(epcNode);
            }
            root.appendChild(element);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Adds the BusinessTransaction List to the XML-File. Possible for -
     * ObjectEvent (optional) - AggregationEvent (optional) - TransactionEvent
     * (at least one)
     * 
     * @param document
     *            the DOM-Tree where is has to inserted
     * @param root
     *            the element, where it has to be added
     * @return if the value had been set in the GUI
     */
    private Boolean addBizTransactionList(final Document document, final Element root, final ArrayList<BizTransaction> bizTransactionList) {
        if (bizTransactionList != null && bizTransactionList.size() > 0
                && !bizTransactionList.get(0).getBizTransID().equals("")) {
            Element element;
            element = document.createElement("bizTransactionList");
            Element bizNode = null;
            for (int i=0; i<bizTransactionList.size(); i++){
                if (!bizTransactionList.get(i).getBizTransID().equals("")){
                                        bizNode = document.createElement("bizTransaction");
                    bizNode.appendChild(document.createTextNode(bizTransactionList.get(i).getBizTransID()));
                    bizNode.setAttribute("type", bizTransactionList.get(i).getBizTransType());
                    element.appendChild(bizNode);
                }
            }
            root.appendChild(element);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Adds the Business Location to the XML-File. Optional for all events.
     * 
     * @param document
     *            the DOM-Tree where is has to inserted
     * @param root
     *            the element, where it has to be added
     * @return if the value had been set in the GUI
     */
    private Boolean addBizLocation(final Document document, final Element root, final String bizLocation) {
        if (!bizLocation.equals("")) {
            Element element;
            element = document.createElement("bizLocation");
            Element bizId = document.createElement("id");
            bizId.appendChild(document.createTextNode(bizLocation));
            element.appendChild(bizId);
            root.appendChild(element);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Adds the ReadPoint to the XML-File. Optional for all events.
     * 
     * @param document
     *            the DOM-Tree where is has to inserted
     * @param root
     *            the element, where it has to be added
     * @return if the value had been set in the GUI
     */
    private Boolean addReadPoint(final Document document, final Element root, final String readPoint) {
        if (!readPoint.equals("")) {
            Element element;
            element = document.createElement("readPoint");
            Element pointId = document.createElement("id");
            pointId.appendChild(document.createTextNode(readPoint));
            element.appendChild(pointId);
            root.appendChild(element);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Adds the Disposition to the XML-File. Optional for all events.
     * 
     * @param document
     *            the DOM-Tree where is has to inserted
     * @param root
     *            the element, where it has to be added
     * @return if the value had been set in the GUI
     */
    private Boolean addDisposition(final Document document, final Element root, final String disposition) {
        if (!disposition.equals("")) {
            Element element;
            element = document.createElement("disposition");
            element.appendChild(document.createTextNode(disposition));
            root.appendChild(element);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Adds the Business Step to the XML-File. Optional for all events.
     * 
     * @param document
     *            the DOM-Tree where is has to inserted
     * @param root
     *            the element, where it has to be added
     * @return if the value had been set in the GUI
     */
    private Boolean addBizStep(final Document document, final Element root, final String bizStep) {
        if (!bizStep.equals("")) {
            Element element;
            element = document.createElement("bizStep");
            element.appendChild(document.createTextNode(bizStep));
            root.appendChild(element);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Adds the action to the XML-File. Required for all Events except the
     * QuantityEvent.
     * 
     * @param document
     *            The DOM-Tree where is has to inserted.
     * @param root
     *            The element, where it has to be added.
     */
    private void addAction(final Document document, final Element root, final String action) {
        Element element;
        element = document.createElement("action");
        element.appendChild(document.createTextNode(action));
        root.appendChild(element);
    }

    /**
     * Adds all the EPC's to the XML-File. Possible for - AggregationEvent
     * (required) - TransactionEvent (required).
     * 
     * @param document
     *            the DOM-Tree where is has to inserted
     * @param root
     *            the element, where it has to be added
     * @return if the value had been set in the GUI
     */
    private Boolean addEpcList(final Document document, final Element root, final String epcList) {
        if (!epcList.equals("")) {
            Element element;
            element = document.createElement("epcList");
            Element epcNode = null;
            StringTokenizer st = new StringTokenizer(epcList);
            while (st.hasMoreTokens()) {
                epcNode = document.createElement("epc");
                epcNode.appendChild(document.createTextNode(st.nextToken()));
                element.appendChild(epcNode);
            }
            root.appendChild(element);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Adds the Parent ID to the XML-File. Possible for - AggregationEvent
     * (optional when action is OBSERVE, required otherwise) - TransactionEvent
     * (Optional).
     * 
     * @param document
     *            the DOM-Tree where is has to inserted
     * @param root
     *            the element, where it has to be added
     * @return if the value had been set in the GUI
     */
    private Boolean addParentId(final Document document, final Element root, final String parentId) {
        if (!parentId.equals("")) {
            Element element;
            element = document.createElement("parentID");
            element.appendChild(document.createTextNode(parentId));
            root.appendChild(element);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Adds the Time of the Event to the XML-File. Required for all Events.
     * 
     * @param document
     *            the DOM-Tree where is has to inserted
     * @param root
     *            the element, where it has to be added
     * @return if the value had been set in the GUI
     */
    private Boolean addEventTime(final Document document, final Element root, final String timeString) {
        if (!timeString.equals("")) {
            Element element;
            element = document.createElement("eventTime");
            element.appendChild(document.createTextNode(timeString));
            root.appendChild(element);
            element = document.createElement("eventTimeZoneOffset");
            element.appendChild(document.createTextNode("+08:00"));
            root.appendChild(element);
            return true;
        } else {
            return false;
        }
    }

    /**
     * Implements a class that holds examples for the EPCIS Capture Interface
     * Client. Uses class CaptureInterfaceEventExample to store them.
     * 
     * @author David Gubler
     */
    private final class ExampleEvents {
        /**
         * List that holds all the examples.
         */
        private List<CaptureEvent> examples = new ArrayList<CaptureEvent>();

        /**
         * Constructor. Sets up the examples. Add examples here if you wish.
         */
        private ExampleEvents() {
            CaptureEvent ex = new CaptureEvent();
            ex.setDescription("DEMO 1: Prototype has been assigned a new EPC");
            ex.setType(0);
            ex.setEventTime("2006-09-20T06:36:17");
            ex.setAction(0);
            ex.setBizStep("urn:accada:demo:bizstep:fmcg:production");
            ex.setDisposition("urn:accada:demo:disp:fmcg:pendingQA");
            ex.setBizLocation("urn:accada:demo:fmcg:ssl:0037000.00729.210");
            ex.setReadPoint("urn:accada:demo:fmcg:ssl:0037000.00729.210,432");
            ex.setEpcList("urn:epc:id:sgtin:0057000.123780.7788");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("DEMO 2: Prototype passed reader in QA lab");
            ex.setType(0);
            ex.setEventTime("2006-09-20T07:33:31.116");
            ex.setAction(1);
            ex.setBizStep("urn:accada:demo:bizstep:fmcg:production");
            ex.setBizLocation("urn:accada:demo:fmcg:ssl:0037000.00729.210");
            ex.setReadPoint("urn:accada:demo:fmcg:ssl:0037000.00729.210,414");
            ex.setEpcList("urn:epc:id:sgtin:0057000.123780.7788");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("DEMO 3: Prototype finished QA process.");
            ex.setType(3);
            ex.setEventTime("2006-09-20T07:53:01");
            ex.setAction(0);
            ex.setBizTransaction("urn:accada:demo:biztrans:fmcg:QApassed",
                    "http://demo.accada.org/QAtracker/q3432q4324");
            ex.setBizLocation("urn:accada:demo:fmcg:ssl:0037000.00729.210");
            ex.setReadPoint("urn:accada:demo:fmcg:ssl:0037000.00729.210,414");
            ex.setEpcList("urn:epc:id:sgtin:0057000.123780.7788");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("DEMO 4: Reader and other products are "
                    + "aggregated onto a pallet.");
            ex.setType(1);
            ex.setAction(0);
            ex.setEventTime("2006-09-20T08:55:04");
            ex.setBizStep("urn:accada:demo:bizstep:fmcg:pickandpack");
            ex.setDisposition("urn:accada:demo:disp:fmcg:readyforpickup");
            ex.setBizLocation("urn:accada:demo:fmcg:ssl:0037000.00729.450");
            ex.setReadPoint("urn:accada:demo:fmcg:ssl:0037000.00729.450,9");
            ex.setBizTransaction("urn:accada:demo:fmcg:btt:po",
                    "http://transaction.accada.org/po/12345678");
            ex.setParentID("urn:x:bar:5:036544:007325");
            ex.setChildEPCs("urn:epc:id:sgtin:0057000.123780.7788 "
                    + "urn:epc:id:sgtin:0057000.123430.2027 "
                    + "urn:epc:id:sgtin:0057000.123430.2028"
                    + "urn:epc:id:sgtin:0057000.123430.2029");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("DEMO 5: Tag has been read "
                    + "at port of Kaohsiung together with other tags");
            ex.setType(0);
            ex.setEventTime("2006-09-20T10:33:31.116");
            ex.setAction(1);
            ex.setBizStep("urn:accada:demo:bizstep:fmcg:shipment");
            ex.setBizLocation("urn:accada:demo:RepublicOfChina:Kaohsiung");
            ex.setReadPoint("urn:accada:demo:fmcg:ssl:0037200.00729.210,414");
            ex.setEpcList("urn:epc:id:sgtin:0057000.123780.7788 "
                    + "urn:epc:id:sgtin:0057000.123430.2027 "
                    + "urn:epc:id:sgtin:0057000.123430.2028"
                    + "urn:epc:id:sgtin:0057000.123430.2029");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("DEMO 6: Tag has been read "
                    + "at port of Rotterdam together with other tags");
            ex.setType(0);
            ex.setEventTime("2006-09-20T12:33:31.116");
            ex.setAction(1);
            ex.setBizStep("urn:accada:demo:bizstep:fmcg:shipment");
            ex.setBizLocation("urn:accada:demo:Netherlands:Rotterdam");
            ex.setReadPoint("urn:accada:demo:fmcg:ssl:0037200.00729.210,234");
            ex.setEpcList("urn:epc:id:sgtin:0057000.123780.7788 "
                    + "urn:epc:id:sgtin:0057000.123430.2027 "
                    + "urn:epc:id:sgtin:0057000.123430.2028"
                    + "urn:epc:id:sgtin:0057000.123430.2029");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("Object has passed a reader "
                    + "during the manufacturing process");
            ex.setType(0);
            ex.setEventTime("2006-04-03T20:33:31.116");
            ex.setAction(1);
            ex.setBizStep("urn:epcglobal:epcis:bizstep:fmcg:production");
            ex.setBizLocation("urn:epcglobal:fmcg:ssl:0037000.00729.210");
            ex.setReadPoint("urn:epcglobal:fmcg:ssl:0037000.00729.210,414");
            ex.setEpcList("urn:epc:id:sgtin:0057000.123780.3167");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("An object has been assigned a new EPC");
            ex.setType(0);
            ex.setEventTime("2006-04-03T22:36:17");
            ex.setAction(0);
            ex.setBizStep("urn:epcglobal:epcis:bizstep:fmcg:production");
            ex.setDisposition("urn:epcglobal:epcis:disp:fmcg:readyforuse");
            ex.setBizLocation("urn:epcglobal:fmcg:ssl:0037000.00729.210");
            ex.setReadPoint("urn:epcglobal:fmcg:ssl:0037000.00729.210,432");
            ex.setEpcList("urn:epc:id:sgtin:0057000.123780.7788");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("Two pallets (identified by EPCs) have been "
                    + "loaded onto a truck");
            ex.setType(0);
            ex.setEventTime("2006-05-09T21:01:44");
            ex.setAction(1);
            ex.setBizStep("urn:epcglobal:epcis:bizstep:fmcg:loading");
            ex.setDisposition("urn:epcglobal:epcis:disp:fmcg:transit");
            ex.setBizLocation("urn:epcglobal:fmcg:ssl:0037000.00729.215");
            ex.setReadPoint("urn:epcglobal:fmcg:ssl:0037000.00729.215,803");
            ex.setEpcList("urn:epc:id:sgtin:0034000.987650.2686 "
                    + "urn:epc:id:sgtin:0034000.987650.3542");
            ex.setBizTransaction("urn:epcglobal:fmcg:btt:po",
                    "http://transaction.acme.com/po/12345678");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("An object has arrived for repair");
            ex.setType(0);
            ex.setEventTime("2006-05-10T04:50:35");
            ex.setAction(1);
            ex.setBizStep("urn:epcglobal:epcis:bizstep:fmcg:received");
            ex.setDisposition("urn:epcglobal:epcis:disp:fmcg:inrepair");
            ex.setBizLocation("urn:epcglobal:fmcg:ssl:0037000.00811.217");
            ex.setReadPoint("urn:epcglobal:fmcg:ssl:0037000.00811.217,058");
            ex.setEpcList("urn:epc:id:sgtin:0034000.987650.2686");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("Three objects have been aggregated onto "
                    + "a barcode-labeled pallet");
            ex.setType(1);
            ex.setAction(0);
            ex.setEventTime("2006-06-01T15:55:04");
            ex.setBizStep("urn:epcglobal:epcis:bizstep:fmcg:pickandpack");
            ex.setDisposition("urn:epcglobal:epcis:disp:fmcg:readyforpickup");
            ex.setBizLocation("urn:epcglobal:fmcg:ssl:0037000.00729.450");
            ex.setReadPoint("urn:epcglobal:fmcg:ssl:0037000.00729.450,9");
            ex.setBizTransaction("urn:epcglobal:fmcg:btt:po",
                    "http://transaction.acme.com/po/12345678");
            ex.setBizTransaction("urn:epcglobal:fmcg:btt:asn",
                    "http://transaction.acme.com/asn/1152");
            ex.setParentID("urn:x:bar:5:036544:007325");
            ex.setChildEPCs("urn:epc:id:sgtin:0057000.123430.2025 "
                    + "urn:epc:id:sgtin:0057000.123430.2027 "
                    + "urn:epc:id:sgtin:0057000.123430.2028");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("Aggregation ended at customer's site");
            ex.setType(1);
            ex.setAction(2);
            ex.setEventTime("2006-06-05T09:26:06");
            ex.setBizLocation("urn:epcglobal:fmcg:ssl:0066000.00101.032");
            ex.setReadPoint("urn:epcglobal:fmcg:ssl:0066000.00101.450,009");
            ex.setBizTransaction("urn:epcglobal:fmcg:btt:po",
                    "http://trans.customer.com/po/E58J3Q");
            ex.setBizTransaction("urn:epcglobal:fmcg:btt:asn",
                    "http://transaction.acme.com/asn/1152");
            ex.setParentID("urn:x:bar:5:036544:007325");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("Physical inventory count: 67 parts counted");
            ex.setType(2);
            ex.setEventTime("2006-01-15T16:15:31");
            ex.setBizStep("urn:epcglobal:epcis:bizstep:fmcg:physinv");
            ex.setDisposition("urn:epcglobal:epcis:disp:fmcg:readyforuse");
            ex.setBizLocation("urn:epcglobal:fmcg:ssl:0066000.00102.007");
            ex.setReadPoint("urn:epcglobal:fmcg:ssl:0066000.00102.014,001");
            ex.setEpcClass("urn:epc:id:sgtin:0069000.957110");
            ex.setQuantity(67);
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("1000 pieces have been produced and can be found "
                    + "at the production site");
            ex.setType(2);
            ex.setEventTime("2006-08-10T18:14:00");
            ex.setBizLocation("urn:epcglobal:fmcg:ssl:0037000.00729.450");
            ex.setReadPoint("urn:epcglobal:fmcg:ssl:0037000.00729.451,2");
            ex.setEpcClass("urn:epc:id:sgtin:0069000.919923");
            ex.setQuantity(1000);
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("Order changed by customer - two "
                    + "more objects added to transaction");
            ex.setType(3);
            ex.setEventTime("2006-08-18T11:53:01");
            ex.setAction(0);
            ex.setBizTransaction("urn:epcglobal:fmcg:btt:po",
                    "http://transaction.acme.com/tracker/6677150");
            ex.setEpcList("urn:epc:id:sgtin:0057000.678930.5003 "
                    + "urn:epc:id:sgtin:0057000.678930.5004");
            examples.add(ex);

            ex = new CaptureEvent();
            ex.setDescription("Transaction is finished");
            ex.setType(3);
            ex.setEventTime("2006-08-20T07:03:51");
            ex.setAction(2);
            ex.setBizTransaction("urn:epcglobal:fmcg:btt:po",
                    "http://transaction.acme.com/tracker/6677150");
            ex.setEpcList("urn:epc:id:sgtin:0057000.678930.5003 "
                    + "urn:epc:id:sgtin:0057000.678930.5004");
            examples.add(ex);
        }
    }

}
